package com.awesome.common.base.mvvm

import android.app.Dialog
import android.content.DialogInterface
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.Window
import android.widget.Toast
import androidx.core.graphics.ColorUtils
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentManager
import androidx.viewbinding.ViewBinding
import com.awesome.common.util.ui.StatusBarUtil
import java.lang.reflect.ParameterizedType

/**
 * Author: JFangZ
 * Email: janezhang1901@163.com
 * Date: 2021/8/26 23:47
 * Description:
 */
abstract class BaseDialogFragment<VB : ViewBinding> : DialogFragment() {
    protected var viewBinding: VB? = null
    var onDismissListener: ((DialogInterface) -> Unit)? = null

    /**
     * Author: JFangZ
     * Email: janezhang1901@163.com
     * Date:2021/4/8 11:32
     * Description:Provided layoutId to setContentView()
     * @return The layoutId of this activity.
     */
    protected abstract fun initLayoutId(): Int

    /**
     * Author: JFangZ
     * Email: janezhang1901@163.com
     * Date:2021/4/8 11:32
     * Description:Do UI init operation,such as findViewByID,setAdapter and so on.
     */
    protected abstract fun initView()

    /**
     * Author: JFangZ
     * Email: janezhang1901@163.com
     * Date:2021/4/8 11:32
     * Description:Do setListener/setCallback operation.
     */
    protected abstract fun setListener()

    /**
     * Author: JFangZ
     * Email: janezhang1901@163.com
     * Date:2019/4/8 11:34
     * Description:Do data init operation,such as network request,read database,read file and so on.
     */
    protected abstract fun initData()

    override fun show(manager: FragmentManager, tag: String?) {
        manager.beginTransaction().remove(this).commit()
        super.show(manager, tag)
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        var dialog = Dialog(context!!)
        // 设置对话框无标题，该方法必须在 setContentView() 之前调用
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
        dialog.setContentView(initContentView()!!)
        dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
        if (dialog.window != null) {
            if (immersive() == true) {
                // 使内容延伸到状态栏下
                StatusBarUtil.setStatusBarTranslucent(activity!!.window, true)
                // 使状态栏透明
                StatusBarUtil.setStatusBarColor(activity!!.window, Color.TRANSPARENT, false)
            } else {
                StatusBarUtil.setStatusBarTranslucent(activity!!.window, false)
            }
            initStatusBarColor()?.also {
                StatusBarUtil.setStatusBarColor(activity!!.window, it, false)
                // 根据状态栏颜色计算出的值小于 0.5 表示状态栏为浅色
                StatusBarUtil.setStatusBarStyle(
                    activity!!.window,
                    ColorUtils.calculateLuminance(StatusBarUtil.getStatusBarColor(activity!!.window)) < 0.5
                )
            }
            // 状态栏深色图标
            initStatusBarDark()?.let { StatusBarUtil.setStatusBarStyle(activity!!.window, it) }
        }
        dialog = customDialog(dialog)
        return dialog
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initView()
        setListener()
        initData()
    }

    override fun onDismiss(dialog: DialogInterface) {
        super.onDismiss(dialog)
        onDismissListener?.invoke(dialog)
    }

    protected open fun initContentView(): View? {
        val vbClazz =
            (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class<VB>
        try {
            viewBinding = vbClazz.getDeclaredMethod("inflate", LayoutInflater::class.java).invoke(
                null, LayoutInflater.from(context)
            ) as VB
            return viewBinding?.root
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return LayoutInflater.from(context).inflate(initLayoutId(), null)
    }

    /**
     * Description:如果对对话框样式有个性需求，可覆写该方法
     * Date:2019/2/19
     */
    protected open fun customDialog(dialog: Dialog): Dialog {
        return dialog
    }

    /**
     * Author: JFangZ
     * Email: janezhang1901@163.com
     * Date:2021/4/8 11:39
     * Description:Make the activity immersive or not,if enable immersion,the status bar will transparent.
     * @return Returns true to enable immersion,false not to enable immersion.
     */
    protected open fun immersive(): Boolean? = null

    /**
     * Author: JFangZ
     * Email: janezhang1901@163.com
     * Date:2021/4/8 11:44
     * Description:Set the color of status bar.
     *
     * @return Color's value.
     */
    protected open fun initStatusBarColor(): Int? = null

    /**
     * Author: JFangZ
     * Email: janezhang1901@163.com
     * Date:2021/4/8 11:45
     * Description:Set the mode of icon in status bar
     *
     * @return Returns true to start dark mode,false to start light mode.
     */
    protected open fun initStatusBarDark(): Boolean? = null

    protected fun toastShort(content: String) = Toast.makeText(
        context, content, Toast.LENGTH_SHORT
    ).show()

    protected fun toastLong(content: String) = Toast.makeText(
        context, content, Toast.LENGTH_LONG
    ).show()

    fun isShowing(): Boolean? = dialog?.isShowing

    fun show(fragmentManager: FragmentManager) = show(
        fragmentManager, javaClass.simpleName + hashCode()
    )
}